"""
从sql导出的数据有时候好像会出现不全的情况
这里从临时医嘱获取某月出院患者fpatno列表，与病案首页出院患者列表做一个交叉
"""

import pandas as pd
import os
import xml.etree.ElementTree as ET
import re

re_date = re.compile(r'(\d*)-(\d*)-(\d*)')
discharge_range_start = '2020-08-01'
discharge_range_end = '2020-09-01'
path_link = os.path.join('data_src','病案首页')
advtemp_file = 'adv_temp.csv'
bl_fp_file = 'bl_fp.csv'

df_bl_fp = pd.read_csv(os.path.join(path_link,bl_fp_file),
                       encoding='gb18030',
                       dtype={
                           'FPATNO':str
                       }).set_index('FPATNO')

df_advtemp = pd.read_csv(
    os.path.join(path_link,advtemp_file),
    encoding='gb18030',
    dtype={
        'FPATNO':str,
    }
).set_index('FPATNO')

def extract_cols(cols_dict:dict,fcontent:str):
    """

    :param cols_dict: currently is bl_fp_quickref in conif.yml, k is fieldname, v is path for element, ONLY SUPPORT SIMPLE ELEMENT(str, int, float, etc)
    :param fcontent: bl_fp csv, fcontent field
    :return: dict, with list comprehensiton and pd.DataFrame we can get a dataframe
    """
    root = ET.fromstring(fcontent)
    rst = {}
    for k,v in cols_dict.items():
        rst[k] = root.find(v).text
    return pd.Series(rst)

cols_dict = {
    '住院号':'./BasiInfor/ZYH',
    '姓名':'./BasiInfor/NAME',
    '入院日期':'./BasiInfor/RYDATE',
    '出院日期':'./BasiInfor/CYDATE',
}

df_bl_fp_extracted = df_bl_fp['FCONTENT'].apply(
    lambda fcontent:extract_cols(cols_dict,fcontent)
)

def date_extract(e):
    if type(e)!=str:
        raise Exception(f'{e} is not str')
    mo = re_date.match(e)
    if(mo):
        date_str_fixed = f'{mo.group(1)}-{("0"+mo.group(2))[-2:]}-{("0"+mo.group(3))[-2:]}'
        return pd.to_datetime(date_str_fixed)


df_bl_fp_extracted['出院日期']=df_bl_fp_extracted['出院日期'].apply(date_extract)
df_bl_fp_extracted['入院日期']=df_bl_fp_extracted['入院日期'].apply(date_extract)
df_bl_fp_filtered = df_bl_fp_extracted[
    (df_bl_fp_extracted['出院日期']>=discharge_range_start) & (df_bl_fp_extracted['出院日期']<discharge_range_end)
]

df_advtemp_discharge = df_advtemp[df_advtemp['FITEMNAME'].apply(lambda e:'出院' in e)]
df_advtemp_discharge_filtered = df_advtemp_discharge[
    (df_advtemp_discharge['FUPDATE']>=discharge_range_start)&(df_advtemp_discharge['FUPDATE']<discharge_range_end)
]

non_included = df_advtemp_discharge_filtered.index.symmetric_difference(df_bl_fp_filtered.index)
assert len(non_included)==0, non_included
